use std::fs::File;

use crate::{
    bytecode::ByteCode,
    lex::{Lex, Token},
    value::Value,
};

#[derive(Debug)]
pub struct ParseProto {
    // 常量表
    pub constants: Vec<Value>,
    // 字节表
    pub byte_codes: Vec<ByteCode>,
}

pub fn load(input: File) -> ParseProto {
    // 创建常量表
    let mut constants = Vec::new();
    // 常见字节码表
    let mut byte_codes = Vec::new();
    // 创建lex词法解析器，输入 .lua 文件，返回迭代器
    let mut lex = Lex::new(input);

    // 循环获取词法分析的Token数据  Name(操作符) String(数据) Eos(结束)
    loop {
        match lex.next() {
            // 匹配操作符
            Token::Name(name) => {
                // `Name LiteralString` as function call
                // 插入到常量表中
                constants.push(Value::String(name));
                // 把字节码插入到字节表中
                byte_codes.push(ByteCode::GetGlobal(0, (constants.len() - 1) as u8));
                if let Token::String(s) = lex.next() {
                    constants.push(Value::String(s));
                    byte_codes.push(ByteCode::LoadConst(1, (constants.len() - 1) as u8));
                    byte_codes.push(ByteCode::Call(0, 1));
                } else {
                    panic!("expected string");
                }
            }
            Token::Eos => break,
            t => panic!("unexpected token: {t:?}"),
        }
    }
    dbg!(&constants);
    dbg!(&byte_codes);

    ParseProto {
        constants,
        byte_codes,
    }
}
